package com.lrkj.lease.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONString;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.lrkj.common.constant.FeeConstants;
import com.lrkj.common.constant.OrgConstants;
import com.lrkj.common.core.domain.entity.OrgTree;
import com.lrkj.common.exception.BaseException;
import com.lrkj.common.utils.DateUtils;
import com.lrkj.common.utils.LrkjDateUtil;
import com.lrkj.common.utils.SecurityUtils;
import com.lrkj.common.utils.uuid.IdUtils;
import com.lrkj.framework.utils.NumberUtils;
import com.lrkj.framework.utils.SerialNumUtil;
import com.lrkj.lease.domain.ContractCategory;
import com.lrkj.lease.domain.LeaseRecord;
import com.lrkj.lease.service.IContractCategoryService;
import com.lrkj.lease.service.ILeaseRecordService;
import com.lrkj.payfee.domain.*;
import com.lrkj.payfee.domain.vo.RoomNormVo;
import com.lrkj.payfee.mapper.RoomNormMapper;
import com.lrkj.payfee.service.*;
import com.lrkj.property.domain.Room;
import com.lrkj.property.mapper.RoomMapper;
import com.lrkj.property.service.IRoomService;
import com.lrkj.system.service.IOrgTreeService;
import com.lrkj.waitress.domain.CustomInfo;
import com.lrkj.waitress.domain.RoomCustom;
import com.lrkj.waitress.service.ICustomInfoService;
import com.lrkj.waitress.service.IRoomCustomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lrkj.lease.mapper.LeaseContractMapper;
import com.lrkj.lease.domain.LeaseContract;
import com.lrkj.lease.service.ILeaseContractService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 租赁合同Service业务层处理
 *
 * @author yajun_ren
 * @date 2022-04-26
 */
@Service
public class LeaseContractServiceImpl implements ILeaseContractService
{
    @Autowired
    private LeaseContractMapper leaseContractMapper;

    @Autowired
    private IRoomCustomService roomCustomService;

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IOrgTreeService orgTreeService;

    @Autowired
    private ICustomInfoService customInfoService;

    @Autowired
    private IRoomNormService roomNormService;

    @Autowired
    private IContractCategoryService iContractCategoryService;

    @Autowired
    private IChargeNormService chargeNormService;


    @Autowired
    private IRuleCostService ruleCostService;

    @Autowired
    private IChargeItemService chargeItemService;

    @Autowired
    private RoomMapper roomMapper;

    @Autowired
    private ILeaseRecordService leaseRecordService;

    /**
     * 查询租赁合同
     *
     * @param id 租赁合同ID
     * @return 租赁合同
     */
    @Override
    public LeaseContract selectLeaseContractById(String id)
    {
        return leaseContractMapper.selectLeaseContractById(id);
    }

    /**
     * 查询租赁合同列表
     *
     * @param leaseContract 租赁合同
     * @return 租赁合同
     */
    @Override
    public List<LeaseContract> selectLeaseContractList(LeaseContract leaseContract)
    {
        return leaseContractMapper.selectLeaseContractList(leaseContract);
    }

    /**
     * 新增租赁合同
     *
     * @param leaseContract 租赁合同
     * @return 结果
     */
    @Override
    public int insertLeaseContract(LeaseContract leaseContract)
    {

        leaseContract.setCreateTime(DateUtils.getNowDate());
        leaseContract.setCreateBy(SecurityUtils.getUsername());
        leaseContract.setId(IdUtils.simpleUUID());
        leaseContract.setNo(this.getNo(FeeConstants.temp_lease_key));
        leaseContract.setStatus("10");
        return leaseContractMapper.insertLeaseContract(leaseContract);
    }

    /**
     * 修改租赁合同
     *
     * @param leaseContract 租赁合同
     * @return 结果
     */
    @Override
    public int updateLeaseContract(LeaseContract leaseContract)
    {
        leaseContract.setUpdateBy(SecurityUtils.getUsername());
        leaseContract.setUpdateTime(DateUtils.getNowDate());
        return leaseContractMapper.updateLeaseContract(leaseContract);
    }

    /**
     * 批量删除租赁合同
     *
     * @param ids 需要删除的租赁合同ID
     * @return 结果
     */
    @Override
    public int deleteLeaseContractByIds(String[] ids)
    {
        for (int i = 0; i < ids.length; i++) {
            LeaseContract leaseContract = leaseContractMapper.selectLeaseContractById(ids[i]);
            if (!leaseContract.getStatus().equals("10")){
                throw new BaseException(String.format("合同编号:%s 已经产生费用单不可删除！", leaseContract.getNo()));
            }
        }
        return leaseContractMapper.deleteLeaseContractByIds(ids);
    }

    /**
     * 删除租赁合同信息
     *
     * @param id 租赁合同ID
     * @return 结果
     */
    @Override
    public int deleteLeaseContractById(String id)
    {
        LeaseContract leaseContract = leaseContractMapper.selectLeaseContractById(id);
        if (!leaseContract.getStatus().equals("10")){
            throw new BaseException(String.format("合同编号:%s 已经产生费用单不可删除！", leaseContract.getNo()));
        }
        return leaseContractMapper.deleteLeaseContractById(id);
    }


    /**
     * 履行合同
     * @param leaseContract
     * @return
     */
    @Override
    @Transactional
    public int appleLease(LeaseContract leaseContract) {
        Room room = roomService.selectRoomById(leaseContract.getResourceId());

        if (room.getStatusCd()=="1002"){
            throw new BaseException("该房间已被入住！");
        }else {
            room.setId(leaseContract.getResourceId());
            //状态为入住
            room.setStatusCd("1002");
            //状态为租户持有
            room.setState("10003");
            room.setOwnerId(leaseContract.getLinkman());
            roomService.updateRoom(room);
            this.roomOwner(leaseContract);
        }
        return 1;
    }

    /**
     * 终止
     * @param leaseContract
     * @return
     */
    @Override
    @Transactional
    public int expriyLease(LeaseContract leaseContract) {


        RuleCost ruleCost=new RuleCost();

        ruleCost.setRoomId(leaseContract.getResourceId());
        ruleCost.setStatus(FeeConstants.charge_status_10001);
        List<RuleCost> ruleCostList = ruleCostService.selectRuleCostList(ruleCost);

        if (ruleCostList.size()>0){
            throw new BaseException("该房间存在未交费的费用，请先缴费");
        }

        leaseContract.setStatus("40");
        int row= leaseContractMapper.updateLeaseContract(leaseContract);


        //修改组织树 清空客户名称
        OrgTree orgTree=new OrgTree();
        orgTree.setId(leaseContract.getResourceId());
        orgTree.setOwnerName("");
        orgTreeService.updateOrgTree(orgTree);


        //删除绑定租户房间
        roomCustomService.deleteRoomCustomById(leaseContract.getResourceId());

        //房屋收费标准状态改为收费结束
        RoomNorm roomNorm=new RoomNorm();
        roomNorm.setRoomId(leaseContract.getResourceId());
        roomNorm.setStatus(FeeConstants.room_norm_status_10002);
        roomNormService.updteByRoomId(roomNorm);

        //修改房间状态
        Room room=new Room();
        room.setId(leaseContract.getResourceId());
        room.setState("10001");
        room.setStatusCd("1001");
        roomMapper.updateRoomState(room);
        return row;
    }



    /**
     * 批量新增租赁合同信息
     *
     * @param leaseContracts 租赁合同对象
     */
    public int batchAddData(List<LeaseContract> leaseContracts)
    {
           return leaseContractMapper.batchAddData(leaseContracts);
    }


    public String getNo(String key) {
        int nextVal = SerialNumUtil.getInstance().nextInt(key);
        return key + NumberUtils.frontCompWithZore(nextVal, 7);
    }

    /**
     * 房屋绑定租户
     * @param leaseContract
     */

    public void roomOwner(LeaseContract leaseContract){

        RoomCustom  roomCustom=new RoomCustom();
        roomCustom.setRoomId(leaseContract.getResourceId());
        roomCustom.setCustomId(leaseContract.getLinkman());
        roomCustom.setOwnerType("1003");
        roomCustomService.insertRoomCustom(roomCustom);


        Room room = roomService.selectRoomById(leaseContract.getResourceId());
        CustomInfo customInfo = customInfoService.selectCustomInfoById(leaseContract.getLinkman());
        orgTreeService.insertOrgTree(room.getId(),room.getRoomNum(), room.getUnitId(),OrgConstants.room, room.getAncestors(), customInfo.getCustomName());

        leaseContract.setStatus("20");
        leaseContractMapper.updateLeaseContract(leaseContract);

        //TODO 绑定房屋收费标准
        this.roomNorm(leaseContract);
    }


    //通过节点ID获取已存在的收费标准
    private Map<String, Object> getRoomNormMap(RoomNormVo roomNorm) {
        Map<String, Object> map = new HashMap<>();
        RoomNorm eg = new RoomNorm();
        eg.setNodeId(roomNorm.getNodeId());
        List<RoomNorm> roomNorms = roomNormService.selectRoomNormList(eg);
        roomNorms.stream().forEach(x -> {
            //房间ID+项目类型ID+费用项目ID+费用标准ID
            String key = x.getRoomId() + x.getProjectId() + x.getChargeId() + x.getNormId();
            map.put(key, x);
        });
        return map;

    }

    /**
     * 绑定房屋收费标准
     * @param leaseContract
     */
    @Transactional
    public void  roomNorm(LeaseContract leaseContract){

        ContractCategory contractCategory = iContractCategoryService.selectContractCategoryById(leaseContract.getContractCategoryId());
        String[] split = contractCategory.getChargeItemIds().split(",");

        List<RoomNorm> list=new ArrayList<>();

        List<RoomNorm> listUpdate=new ArrayList<>();
        RoomNormVo vo=new RoomNormVo();
        vo.setNodeId(leaseContract.getResourceId());
        for (int i = 0; i < split.length; i++) {
            Map<String, Object> roomNormMap = this.getRoomNormMap(vo);

            //根据收费标准查询收费项目及费用类型
            ChargeNorm chargeNorm = chargeNormService.selectChargeNormById(split[i]);

            //房间ID+项目类型ID+费用项目ID+费用标准ID
            String key = leaseContract.getResourceId() + chargeNorm.getProjectId() + chargeNorm.getChargeId() + chargeNorm.getNormId();

            if (!roomNormMap.containsKey(key)) {

                RoomNorm bean=new RoomNorm();
                bean.setRoomNormId(IdUtils.simpleUUID());
                bean.setNormId(split[i]);
                bean.setChargeId(chargeNorm.getChargeId());
                bean.setProjectId(chargeNorm.getProjectId());
                Room room = roomService.selectRoomById(leaseContract.getResourceId());
                bean.setDeptId(room.getDeptId());
                bean.setCommunityId(room.getCommunityId());
                bean.setFloorId(room.getFloorId());
                bean.setUnitId(room.getUnitId());
                bean.setRoomId(room.getId());
                bean.setBeginChargeTime(leaseContract.getBeginTime());
                bean.setFinishChargetime(leaseContract.getFinishTime());
                bean.setCreateBy(SecurityUtils.getUsername());
                bean.setCreateTime(DateUtils.getNowDate());
                bean.setStatus(FeeConstants.room_norm_status_10001);
                //交齐年月
                bean.setDeliveryTime(LrkjDateUtil.addDay(leaseContract.getBeginTime(), -1));
                //下一次开始收费时间
                bean.setNextBeginChargeTime(leaseContract.getBeginTime());
                //下一次结束收费时间
                bean.setNextFinishChargetime(LrkjDateUtil.getLastMonthDay(leaseContract.getBeginTime()));
                bean.setAmountSpecified(new BigDecimal(0.00));
                bean.setAncestors(room.getAncestors() + "," + room.getId());

                list.add(bean);
            }else {
                RoomNorm Updatebean=new RoomNorm();
                Updatebean.setRoomNormId(IdUtils.simpleUUID());
                Updatebean.setNormId(split[i]);
                Updatebean.setChargeId(chargeNorm.getChargeId());
                Updatebean.setProjectId(chargeNorm.getProjectId());
                Room room = roomService.selectRoomById(leaseContract.getResourceId());
                Updatebean.setDeptId(room.getDeptId());
                Updatebean.setCommunityId(room.getCommunityId());
                Updatebean.setFloorId(room.getFloorId());
                Updatebean.setUnitId(room.getUnitId());
                Updatebean.setRoomId(room.getId());
                Updatebean.setBeginChargeTime(leaseContract.getBeginTime());
                Updatebean.setFinishChargetime(leaseContract.getFinishTime());
                Updatebean.setCreateBy(SecurityUtils.getUsername());
                Updatebean.setCreateTime(DateUtils.getNowDate());
                Updatebean.setStatus(FeeConstants.room_norm_status_10001);
                //交齐年月
                Updatebean.setDeliveryTime(LrkjDateUtil.addDay(leaseContract.getBeginTime(), -1));
                //下一次开始收费时间
                Updatebean.setNextBeginChargeTime(leaseContract.getBeginTime());
                //下一次结束收费时间
                Updatebean.setNextFinishChargetime(LrkjDateUtil.getLastMonthDay(leaseContract.getBeginTime()));
                Updatebean.setAmountSpecified(new BigDecimal(0.00));
                Updatebean.setAncestors(room.getAncestors() + "," + room.getId());

                listUpdate.add(Updatebean);
            }

        }
        roomNormService.updateByBatchByRoom(listUpdate);
        roomNormService.doSaveList(list);

        //TODO 添加常规费用单
        this.ruleCost(leaseContract);

        //TODO 租金费用单
        this.roomRent(leaseContract);
    }


    /**
     * 添加常规费用单
     * @param x
     */
    public void ruleCost(LeaseContract x){

        RuleCost bean=new RuleCost();
        bean.setChargeId(x.getChargeId());
        ChargeItem chargeItem = chargeItemService.selectChargeItemById(x.getChargeId());
        bean.setMoneys(x.getChargeMoneys());
        bean.setOwnerId(x.getLinkman());
        bean.setProjectId(chargeItem.getProjectId());
        bean.setReceivableTime(x.getBeginTime());
        bean.setRoomId(x.getResourceId());
        bean.setStatus("10001");
        ruleCostService.insertRuleCost(bean);
    }


    /**
     * 租金费用单
     * @param x
     */
    public void roomRent(LeaseContract x){
        RoomNorm bean=new RoomNorm();

        bean.setRoomNormId(IdUtils.simpleUUID());
        ChargeNorm chargeNorm = chargeNormService.selectChargeNormById(x.getRoomNormId());
        bean.setProjectId(chargeNorm.getProjectId());
        bean.setChargeId(chargeNorm.getChargeId());
        bean.setNormId(x.getRoomNormId());

        Room room = roomService.selectRoomById(x.getResourceId());
        bean.setDeptId(room.getDeptId());
        bean.setCommunityId(room.getCommunityId());
        bean.setFloorId(room.getFloorId());
        bean.setUnitId(room.getUnitId());
        bean.setRoomId(room.getId());
        bean.setBeginChargeTime(x.getBeginTime());
        bean.setFinishChargetime(x.getFinishTime());
        bean.setCreateBy(SecurityUtils.getUsername());
        bean.setCreateTime(DateUtils.getNowDate());
        bean.setStatus(FeeConstants.room_norm_status_10001);
        //交齐年月
        bean.setDeliveryTime(LrkjDateUtil.addDay(x.getBeginTime(), -1));

        //下一次开始收费时间
        bean.setNextBeginChargeTime(x.getBeginTime());
        if (x.getMarkerRule().equals(FeeConstants.charge_generate_type_10)){
            int num =0;
            if (x.getChargingCycle().equals(FeeConstants.chargeing_cycle_type_10001)){
                num=0;
            }else if (x.getChargingCycle().equals(FeeConstants.chargeing_cycle_type_10002)){
                num=2;
            }else if (x.getChargingCycle().equals(FeeConstants.chargeing_cycle_type_10003)){
                num=11;
            }
            //自然收费周期
            bean.setNextFinishChargetime(LrkjDateUtil.getLastMonthDay(LrkjDateUtil.subMonth(x.getBeginTime(),num)));//下一次结束收费时间

        }else if (x.getMarkerRule().equals(FeeConstants.charge_generate_type_20)){
            int num =0;
            if (x.getChargingCycle().equals(FeeConstants.chargeing_cycle_type_10001)){
                num=1;
            }else if (x.getChargingCycle().equals(FeeConstants.chargeing_cycle_type_10002)){
                num=3;
            }else if (x.getChargingCycle().equals(FeeConstants.chargeing_cycle_type_10003)){
                num=12;
            }
            //顺延周期
            bean.setNextFinishChargetime(DateUtil.offsetDay(DateUtil.offsetMonth(x.getBeginTime(), num), -1));//下一次结束收费时间
        }
        bean.setAmountSpecified(x.getRoomNormMoney());
        bean.setAncestors(room.getAncestors() + "," + room.getId());

        List<RoomNorm> list=new ArrayList<>();
        list.add(bean);
        roomNormService.doSaveList(list);

    }


    /**
     * 合同变更记录
     * @param leaseContract
     * @return
     */
    @Override
    @Transactional
    public int beforeRecord(LeaseContract leaseContract) {
        //变更前
        LeaseContract contract = leaseContractMapper.selectLeaseContractById(leaseContract.getId());
        LeaseRecord record=new LeaseRecord();
        record.setContent(JSONObject.toJSONString(contract));
        record.setRecordType("10");
        record.setContractId(leaseContract.getId());
        leaseRecordService.insertLeaseRecord(record);


        //修改变更记录
        leaseContract.setReletStatus("1");
        int updateLeaseContract = leaseContractMapper.updateLeaseContract(leaseContract);

        //变更后
        LeaseRecord recordUp=new LeaseRecord();
        recordUp.setContent(JSONObject.toJSONString(leaseContract));
        recordUp.setRecordType("20");
        recordUp.setContractId(leaseContract.getId());
        recordUp.setLeaseCause(leaseContract.getLeaseCause());
        leaseRecordService.insertLeaseRecord(recordUp);


        //TODO 添加房间收费标准
        this.roomNorm(leaseContract);
        return updateLeaseContract;
    }


}
